package com.dede.state;

import android.content.Context;
import android.support.annotation.NonNull;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.dede.state.component.LoadingComponent;
import com.dede.state.component.StateComponent;
import com.dede.state.component.SuccessComponent;

import java.util.HashMap;
import java.util.Map;

/**
 * 继承与帧布局，将ContentView替换为StateLayout，在StateLayout内管理不同状态的显示隐藏，最多显示两层子View
 *
 * @author hsh
 *         2018/1/22 16:13.
 */
public final class StateLayout extends FrameLayout {

    private final Map<Class<? extends StateComponent>, StateComponent> componentMap;
    private Class<? extends StateComponent> preClass;
    private StateComponent.ReloadListener reloadListener;

    private StateLayout(@NonNull Context context) {
        super(context);
        componentMap = new HashMap<>();
    }

    /**
     * 只能代码初始化
     *
     * @param context
     * @param listener 重新加载回掉
     */
    public StateLayout(@NonNull Context context, StateComponent.ReloadListener listener) {
        this(context);
        reloadListener = listener;
    }

    /**
     * 添加状态组件
     *
     * @param stateComponent
     */
    public void addStateComponent(StateComponent stateComponent) {
        StateComponent copy = stateComponent.copy();
        copy.setParams(getContext(), reloadListener);
        componentMap.put(stateComponent.getClass(), copy);
    }

    /**
     * 设置成功组件
     *
     * @param successComponent
     */
    public void setSuccessComponent(SuccessComponent successComponent) {
        componentMap.put(successComponent.getClass(), successComponent);
        addView(successComponent.getRootView(), 0);
    }

    /**
     * 显示成功状态
     */
    public void showSuccess() {
        show(SuccessComponent.class);
    }

    /**
     * 显示指定状态
     *
     * @param clazz
     */
    public void show(Class<? extends StateComponent> clazz) {
        checkStateComponentExist(clazz);

        if (clazz == preClass) {// 状态没有改变return
            return;
        }

        if (getChildCount() > 1) {// 说明不是成功状态，成功状态子View个数为1
            StateComponent component = componentMap.get(preClass);
            if (component != null) {
                removeView(component.getRootView());
            }
        }

        SuccessComponent successComponent = (SuccessComponent) componentMap.get(SuccessComponent.class);
        if (clazz == SuccessComponent.class) {
            successComponent.show();// 如果是成功状态，直接显示
        } else {
            StateComponent stateComponent = componentMap.get(clazz);
            ViewGroup.LayoutParams params = stateComponent.getRootView().getLayoutParams();
            /**
             * 如果使用的xml填充的View,是没有LayoutParams
             *  @see StateComponent#getRootView
             */
            if (params == null) {
                LayoutParams defaultParams = generateDefaultLayoutParams();
                defaultParams.gravity = Gravity.CENTER;
                params = defaultParams;
            }

            addView(stateComponent.getRootView(), 1, params);// add rootView

            // 是否显示成功页面
            if (stateComponent.isShowSuccess()) {
                successComponent.show();
            } else {
                successComponent.hide();
            }

            // 如果是Loading状态，设置StateLayout
            if (stateComponent instanceof LoadingComponent) {
                LoadingComponent loadingComponent = (LoadingComponent) stateComponent;
                if (loadingComponent.isCancelable()) {
                    loadingComponent.setStateLayout(this);
                }
            }
        }
        preClass = clazz;
    }

    /**
     * 判断是否存在当前页面
     *
     * @param clazz
     */
    private void checkStateComponentExist(Class<? extends StateComponent> clazz) {
        if (!componentMap.containsKey(clazz)) {
            throw new IllegalArgumentException(String.format("The StateComponent (%s) is nonexistent.", clazz
                    .getSimpleName()));
        }
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        int childCount = getChildCount();
        if (childCount >= 2) {
            // 最多两个子View
            throw new IllegalArgumentException("StateLayout child count:" + childCount);
        }
        super.addView(child, index, params);
    }

    /**
     * 修改组件布局
     *
     * @param clazz
     * @param transport
     */
    public void customComponent(Class<? extends StateComponent> clazz, Transport transport) {
        if (transport == null) return;

        checkStateComponentExist(clazz);
        StateComponent component = componentMap.get(clazz);
        transport.alter(component.getRootView());
    }
}
